/************************************
 * created by Tonk (tonk@ctonk.com) *
 ************************************/

// object.h

#ifndef OBJECT_H
#define OBJECT_H

#include "definitions.h"
#include <string>
#include <fstream>
#include "area.h"
#include "room.h"

enum OBJECT_TYPE {	OT_ERROR,	// Used for errors in static method return statements.
					ACCESSORY,
					ARMOR,
					BODY_PART,
					CLOTHING,
					COIN,
					CONTAINER,
					DRINK,
					FOOD,
					FURNITURE,
					JEWELRY,
					SCROLL,
					TRASH,
					WAND,
					WEAPON	};

/////////////////////////////////////////// base object ///////////////////////////////////////////
class Object {
	protected:
		int			_vnum;
		OBJECT_TYPE _type;
		int			_weight;
		int			_flags;
		std::string _keywords;
		std::string _short;
		std::string _long;
		std::string	_desc;

		void	copyObjectData( Object& );
		std::string objectDisplay( std::string );

	public:
		Object();
		Object( Object& );
		virtual ~Object();

		Object& operator = ( Object& );

		void	setVnum( int );
		int		getVnum();
		void	setType( OBJECT_TYPE );
		OBJECT_TYPE getType();
		void	setWeight( int );
		int		getWeight();
		void	setFlags( int );
		int		getFlags();
		void	setKeywords( std::string );
		std::string& getKeywords();
		void	setShort( std::string );
		std::string getShort();
		void	setLong( std::string );
		std::string getLong();
		void	setDesc( std::string );
		std::string& getDesc();

		// general methods...
		void	oSave( std::ofstream& );
		virtual void	save( std::ofstream& ) = 0;
		virtual void	load( std::ifstream& ) = 0;
		virtual void	copy( Object* ) = 0;
		virtual std::string display() = 0;

		// static data...
		static int numObjects;

		// static methods...
		static Object*		getNewObject( OBJECT_TYPE );
		static std::string	stringType( OBJECT_TYPE );
		static OBJECT_TYPE	objectType( std::string );

		// methods for derived class Armor...
		// methods for derived class Accessory...
		// methods for derived class Body_Part...
		// methods for derived class Coin...
		// methods for derived class Clothing...
		// methods for derived class Container...
		virtual void	setMaxWeight( int ) {};
		virtual int		getMaxWeight() { return 0; }
		virtual void	setMaxSize( int ) {};
		virtual int		getMaxSize() { return 0; }
		virtual std::list< Object* > getContents() { std::list< Object* > temp; return temp; }
		virtual bool	addItem( Object* ) { return false; }
		virtual bool	dropItem( std::string ) { return false; }
		virtual Object*	getItem( std::string ) { Object* temp = NULL; return temp; }
		// methods for derived class Drink...
		// methods for derived class Food...
		// methods for derived class Furniture...
		// methods for derived class Jewelry...
		// methods for derived class Scroll...
		// methods for derived class Trash...
		// methods for derived class Wand...
		// methods for derived class Weapon...
};

/////////////////////////////////////////// accessory object ///////////////////////////////////////////
class Accessory: public Object {
	protected:

	public:
		Accessory();
		Accessory( Accessory& );
		~Accessory();

		Accessory& operator = ( Accessory& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// armor object ///////////////////////////////////////////
class Armor: public Object {
	protected:

	public:
		Armor();
		Armor( Armor& );
		~Armor();

		Armor& operator = ( Armor& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// body_part object ///////////////////////////////////////////
class Body_Part: public Object {
	protected:

	public:
		Body_Part();
		Body_Part( Body_Part& );
		~Body_Part();

		Body_Part& operator = ( Body_Part& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// clothing object ///////////////////////////////////////////
class Clothing: public Object {
	protected:

	public:
		Clothing();
		Clothing( Clothing& );
		~Clothing();

		Clothing& operator = ( Clothing& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// coin object ///////////////////////////////////////////
class Coin: public Object {
	protected:

	public:
		Coin();
		Coin( Coin& );
		~Coin();

		Coin& operator = ( Coin& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// container object ///////////////////////////////////////////
class Container: public Object {
	protected:
		int		_weight;
		int		_maxWeight;
		int		_maxSize;
		std::list< Object* >	_contents;

		void	readObject( std::ifstream& );
		Object*	findObject( std::string );
		bool	canFit( Object* );
		void	setWeight( int );
		void	addWeight( int );
		void	dropWeight( int );

	public:
		Container();
		Container( Container& );
		~Container();

		Container& operator = ( Container& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );
		std::string	display();

		// Overrides from Object...
		int		getWeight();
		void	setMaxWeight( int );
		int		getMaxWeight();
		void	setMaxSize( int );
		int		getMaxSize();
		std::list< Object* > getContents();
		bool	addItem( Object* );
		bool	dropItem( std::string );
		Object* getItem( std::string );
};

/////////////////////////////////////////// drink object ///////////////////////////////////////////
class Drink: public Object {
	protected:

	public:
		Drink();
		Drink( Drink& );
		~Drink();

		Drink& operator = ( Drink& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// food object ///////////////////////////////////////////
class Food: public Object {
	protected:

	public:
		Food();
		Food( Food& );
		~Food();

		Food& operator = ( Food& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// furniture object ///////////////////////////////////////////
class Furniture: public Object {
	protected:

	public:
		Furniture();
		Furniture( Furniture& );
		~Furniture();

		Furniture& operator = ( Furniture& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// jewelry object ///////////////////////////////////////////
class Jewelry: public Object {
	protected:

	public:
		Jewelry();
		Jewelry( Jewelry& );
		~Jewelry();

		Jewelry& operator = ( Jewelry& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// scroll object ///////////////////////////////////////////
class Scroll: public Object {
	protected:

	public:
		Scroll();
		Scroll( Scroll& );
		~Scroll();

		Scroll& operator = ( Scroll& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// trash object ///////////////////////////////////////////
class Trash: public Object {
	protected:

	public:
		Trash();
		Trash( Trash& );
		~Trash();

		Trash& operator = ( Trash& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// wand object ///////////////////////////////////////////
class Wand: public Object {
	protected:

	public:
		Wand();
		Wand( Wand& );
		~Wand();

		Wand& operator = ( Wand& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};

/////////////////////////////////////////// weapon object ///////////////////////////////////////////
class Weapon: public Object {
	protected:

	public:
		Weapon();
		Weapon( Weapon& );
		~Weapon();

		Weapon& operator = ( Weapon& );

		void	save( std::ofstream& );
		void	load( std::ifstream& );
		void	copy( Object* );

		std::string	display();
};



#endif // #ifndef OBJECT_H
